/*
 * Copyright (C) 2025 Tsingteng MicroSystem
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file rw_tag.h
 * @brief 定义卡片操作API
 */

#ifndef _RW_TAG_H_
#define _RW_TAG_H_

#include "nci_feature.h"
#if IS_FEATURE_ON(NCI_FEATURE_RW)

#include "nci_base.h"
#include "nfa_rw.h"

#define NCI_RW_NDEF_FL_READ_ONLY 0x01
#define NCI_RW_NDEF_FL_FORMATED 0x02
#define NCI_RW_NDEF_FL_SUPPORTED 0x04
#define NCI_RW_NDEF_FL_UNKNOWN 0x80
#define NCI_RW_NDEF_FL_FORMATABLE 0x10
#define NCI_RW_NDEF_FL_SOFT_LOCKABLE 0x20
#define NCI_RW_NDEF_FL_HARD_LOCKABLE 0x40
#define NCI_RW_NDEF_FL_OTP_LOCKABLE 0x80

#define NCI_RW_DEFAULT_MAX_RETRY_COUNT 5

/** @brief 卡片操作API定义 */
typedef struct {
    /**
     * @brief 指令传输失败后最大重试次数
     */
    uint8_t max_retry_count;
    /**
     * @brief 卡片进场后第一次激活时被调用
     * @note 可以在此函数中完成各个变量的初始化
     * @param *p_tag 卡片信息
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*on_connect)(tNCI_RW_TAG *p_tag);
    /**
     * @brief 卡片离场时被调用（RF状态进入DISCOVERY或是IDLE状态的场景）
     * @note 此函数的实现中需要对内存进行完全的清理
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*on_disconnect)();
    /**
     * @brief 卡片被激活时调用
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*on_select)();
    /**
     * @brief 卡片即将被去激活时调用（RF状态即将切换到W4_HOST_SELECT之前）
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*on_deselect)(tNCI_RW_TAG *p_tag);
    /**
     * @brief 检查卡片响应数据的是否有效，一般用于卡片ACK/NAK检测
     * @param[inout] p_rsp 接收到的数据指针，可以修改其内容
     * @param[inout] rsp_len 接收到的数据长度，可以修改其内容
     * @return 允许此结果返回给上层返回NCI_STATUS_OK, 否则返回其他错误码
     */
    tNCI_STATUS (*check_transceive_resp)(uint8_t *p_rsp, uint16_t *rsp_len);
    /**
     * @brief 当给卡片传输指令失败时，是否需要断开连接
     *
     * @param[in] p_cmd 传输的指令
     * @param[in] statue 传输失败的状态
     * @return 需要断开连接返回true, 否则返回false
     */
    bool (*disconnect_when_transmit_fail)(tNCI_BUF *p_cmd, tNCI_STATUS statue);
    /**
     * @brief 检测卡片是否保存了NDEF格式的数据
     * @param *p_ndef_info[out] 输出NDEF信息的结构体，只有在返回成功时有效
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*ndef_detect)(tNCI_RW_NDEF_INFO *p_ndef_info);
    /**
     * @brief 从卡片中读取NDEF数据
     * @param *p_rsp[out] 输出NDEF数据的结构体，只有在返回成功时有效
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*ndef_read)(tNCI_RSP *p_rsp);
    /**
     * @brief 向卡片写入NDEF数据
     * @param *p_data[in] 待写入的数据指针
     * @param len 待写入数据的长度
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*ndef_write)(uint8_t *p_data, uint32_t len);
    /**
     * @brief 将卡片格式化为NDEF格式
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*ndef_format)();
    /**
     * @brief 检测卡片是否还在场强中
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*presence_check)();
    /**
     * @brief 将卡片设置为只读模式
     * @param is_hard_lock 是否为硬锁
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*set_tag_read_only)(bool is_hard_lock);
    /**
     * @brief 判断卡片是否支持格式化成NDEF格式
     * @return 成功返回NCI_STATUS_OK, 其他情况返回对应错误码
     */
    tNCI_STATUS (*is_ndef_formatable)();
} tNCI_RW_TAG_API;

#endif // IS_FEATURE_ON(NCI_FEATURE_RW)

#endif /* _RW_TAG_H_ */
